//    Copyright (c) 2009 Elwyn Malethan
//
//    This file is part of SeemoreJ.
//
//    SeemoreJ is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    SeemoreJ is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.

//    You should have received a copy of the GNU General Public License
//    along with SeemoreJ.  If not, see <http://www.gnu.org/licenses/>.

package com.malethan.seemorej.dao;

import java.io.Serializable;
import java.util.List;


/**
 * Generic DAO (Data Access Object) with common methods to CRUD POJOs.
 *
 * <p>Extend this interface if you want typesafe (no casting necessary) DAO's for your
 * domain objects.
 *
 * @author Based on original by <a href="mailto:bwnoll@gmail.com">Bryan Noll</a>
 */
public interface GenericDao<T, PK extends Serializable> {

    /**
     * Generic method used to get all objects of a particular type. This
     * is the same as lookup up all rows in a table.
     * @return List of populated objects
     */
    public List<T> find();


    /**
     * Generic method used to get all objects of a particular type. This
     * is the same as lookup up all rows in a table. If offset and limit
     * are > -1 then a subset of the results are returned.
     *
     * @param offset the 0 based index of the first result
     * @param limit the max number of records to return
     * @return a subset of all results
     */
    public List<T> find(int offset, int limit);

    /**
     * Counts the total number of records for the given entity.
     *
     * @return total number of records
     */
    public Long count();

    /**
     * Generic method to get an object based on class and identifier. An
     * ObjectRetrievalFailureException Runtime Exception is thrown if
     * nothing is found.
     *
     * @param id the identifier (primary key) of the object to get
     * @return a populated object
     */
    public T load(PK id);

    /**
     * Checks for existence of an object of type T using the id arg.
     * @param id
     * @return - true if it exists, false if it doesn't
     */
    public boolean exists(PK id);

    /**
     * Generic method to save an object - handles both update and insert.
     * @param object the object to save
     */
    public T save(T object);

    /**
     * Generic method for saving or updating an object. This one walks the object graph and is not tolerant of stale
     * objects
     *
     * @param object
     * @return
     */
    public T saveOrUpdate(T object);

    /**
     * Generic method to delete an object based on class and id
     * @param id the identifier (primary key) of the object to remove
     */
    public void remove(PK id);

    /**
     * Generic method to delete an object based on class and instance
     * @param object the instance to remove/delete
     */
    public void remove(T object);

    /**
     * Implementations should validate the instance for correct/valid state
     * @param object the instance to validate
     * @return
     */
    public ValidationMessage[] validate(T object);
}